WKWebView的那些坑
前一篇文章中介绍了WKWebView的一下常用属性以及常用API,那么在这篇文章中将主要讲述WKWebView在使用过程中遇到的一些坑。
1.白屏问题
在UIWebView上个当内存占用太大时,app会直接crash,而在WKWebView上内存占用太大时,WebContent Process 会 crash,从而导致页面白屏。
解决办法:
在iOS9之后WKNavigtionDelegate 新增了一个回调函数:
1 | - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView; |
在WebContent Process即将crash的时候,系统会调用上面的函数,这个时候webView.URL还不为空,所以我们直接在上面的这个回调里面调用[webView reload],问题得到解决。
2.双击页面导致客户端崩溃问题
报错信息:
1 | [WKContentView isSecureTextEntry]: unrecognized selector sent to instance 0x101bd5000 |
从这个报错信息表明WKContentView没有找到isSecureTextEntry方法,在查找各种资料无果后决定用runtime的方式给WKContentView加上该方法,简单粗暴。
1 | + (void)progressWKContentViewCrash |
以上progressWKContentViewCrash方法只需要调用一次即可,无需多次调用。
3.页面无法释放问题
在实际使用过程当中,发现使用了WKWebView的界面始终无法释放,在排除了其他因素之后,把目光转向了WKWebView。经过排查之后发现,在初始化webview的时候是这样的:
1 | webview = [[WKWebView alloc]initWithFrame:frame configuration:configuration]; |
然而webview为了与js进行交互,configuration的userContentController属性添加了一个WKScriptMessageHandler:
1 | [configuration.userContentController addScriptMessageHandler:self name:@"methodName"]; |
因为webview的持有者是controller,然后controller又被configuration.userContentController强引用,所以导致页面无法释放。所以这里建议将handler设置成一个管理类,并且在页面的delloc中将其移除。
1 | [configuration.userContentController addScriptMessageHandler:handlerManager name:@"methodName"]; |
4.Alert相关问题
4.1、Js执行alert方法不弹出alert问题
首先确定webview的回调中已经实现了alert,然后在判断alert弹出时是否有其他界面正在弹出或消失,若有,则在动画结束之后再弹出alert。
1 | -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler; |
4.2、Alert崩溃问题
确保最后的completionHandler被执行。
5、其它问题
5.1、视频自动播放
WKWebView 需要通过WKWebViewConfiguration.mediaPlaybackRequiresUserAction设置是否允许自动播放,但一定要在 WKWebView 初始化之前设置,在 WKWebView 初始化之后设置无效。
5.2、goBack API问题
WKWebView 上调用 -[WKWebView goBack], 回退到上一个页面后不会触发window.onload()函数、不会执行JS。
5.3、页面滚动速率
WKWebView 需要通过scrollView delegate调整滚动速率:
1 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView |